<template>
  <div 
    :id="id"
    :class="[
      'component-group',
      { 'selected': isSelected }
    ]"
    @click.stop="handleSelect"
    draggable="true"
    @dragstart="handleDragStart"
    @drag="handleDrag"
    @dragend="handleDragEnd"
    @dragover.prevent
    @drop.stop="handleDrop"
  >
    <div class="group-handle">
      <MenuOutlined />
    </div>
    
    <!-- 组件列表 -->
    <div class="group-content">
      <DraggableItem
        v-for="component in groupComponents"
        :key="component.id"
        :id="component.id"
        :configData="component.configData"
      />
    </div>
    
    <div class="group-actions">
      <a-space>
        <a-button type="text" size="small" @click.stop="handleUngroup">
          <template #icon><SplitCellsOutlined /></template>
        </a-button>
        <a-button type="text" size="small" @click.stop="handleCopy">
          <template #icon><CopyOutlined /></template>
        </a-button>
        <a-button type="text" size="small" @click.stop="handleDelete">
          <template #icon><DeleteOutlined /></template>
        </a-button>
      </a-space>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { MenuOutlined, CopyOutlined, DeleteOutlined, SplitCellsOutlined } from '@ant-design/icons-vue';
import { useEditorStore } from '@/stores/editor';
import DraggableItem from './DraggableItem.vue';

const props = defineProps<{
  id: string;
  componentIds: string[];
}>();

const editorStore = useEditorStore();

const isSelected = computed(() => 
  editorStore.selectedComponentId === props.id
);

const groupComponents = computed(() => 
  editorStore.canvasComponents.filter(comp => props.componentIds.includes(comp.id))
);

// 拖拽相关状态和方法
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });
const elementRect = ref<DOMRect | null>(null);

const handleDragStart = (event: DragEvent) => {
  if (!event.target || !(event.target instanceof HTMLElement)) return;
  
  isDragging.value = true;
  elementRect.value = event.target.getBoundingClientRect();
  
  dragOffset.value = {
    x: event.clientX - elementRect.value.left,
    y: event.clientY - elementRect.value.top,
  };
  
  editorStore.setDraggingId(props.id);
};

const handleDrag = (event: DragEvent) => {
  if (!isDragging.value || !event.clientX || !event.clientY) return;
  
  const newRect = new DOMRect(
    event.clientX - dragOffset.value.x,
    event.clientY - dragOffset.value.y,
    elementRect.value?.width || 0,
    elementRect.value?.height || 0
  );
  
  elementRect.value = newRect;
};

const handleDragEnd = () => {
  isDragging.value = false;
  elementRect.value = null;
  editorStore.setDraggingId(null);
};

const handleDrop = (event: DragEvent) => {
  event.preventDefault();
  const sourceId = event.dataTransfer?.getData('component-id');
  if (sourceId && sourceId !== props.id) {
    editorStore.swapComponents(sourceId, props.id);
  }
};

const handleSelect = () => {
  editorStore.selectComponent(props.id);
};

const handleUngroup = () => {
  editorStore.ungroupComponents(props.id);
};

const handleCopy = () => {
  editorStore.duplicateGroup(props.id);
};

const handleDelete = () => {
  editorStore.deleteGroup(props.id);
};
</script>

<style lang="less" scoped>
.component-group {
  border: 1px dashed #d9d9d9;
  border-radius: 8px;
  padding: 24px;
  position: relative;
  margin-bottom: 16px;
  transition: all 0.3s ease;
  
  &.selected {
    border-color: #1890ff;
    border-style: solid;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  }
  
  &:hover {
    border-color: #1890ff;
    
    .group-actions {
      opacity: 1;
    }
  }
  
  .group-handle {
    position: absolute;
    left: 8px;
    top: 8px;
    cursor: move;
    color: #999;
  }
  
  .group-content {
    margin: 8px 0;
  }
  
  .group-actions {
    position: absolute;
    right: 8px;
    top: 8px;
    opacity: 0;
    transition: opacity 0.3s;
  }
}
</style> 